<template>
  <el-dialog v-model="visible" :title="isEdit ? '更新品牌' : '绑定品牌'" width="600px" :close-on-click-modal="false" @close="close">
    <el-form ref="formRef" :model="form" :rules="rules" label-width="110px">
      <!-- 品牌类型 -->
      <el-form-item label="品牌类型" prop="brandType" v-if="!isEdit">
        <el-radio-group v-model="form.brandType">
          <el-radio-button label="1">自有品牌</el-radio-button>
          <el-radio-button label="2">代理品牌</el-radio-button>
        </el-radio-group>
      </el-form-item>

      <!-- 品牌名称 -->
      <el-form-item label="品牌名称" prop="brandName" v-if="!isEdit">
        <el-select
          v-model="form.brandName"
          value-key="id"
          filterable
          remote
          placeholder="请输入或选择品牌"
          :remote-method="queryBrand"
          :loading="brandLoading"
          style="width: 240px"
          @change="handleBrandChange"
          @keydown="handleKeydown"
        >
          <!-- 已有品牌 -->
          <el-option v-for="b in brandOptions" :key="b.id" :label="b.brandName" :value="b" />
        </el-select>
        <div class="form-tip">品牌名需与下方提交的品牌logo一致</div>
      </el-form-item>

      <el-form-item label="品牌名称" prop="brandName" v-if="isEdit">
        <el-input
          v-model="form.brandName"
          placeholder="请输入品牌名称"
          maxlength="30"
          show-word-limit
          @input="handleNoSpaceInput('brandName', $event)"
          @keydown="handleKeydown"
        />
        <div class="form-tip">品牌名需与下方提交的品牌logo一致</div>
      </el-form-item>

      <!-- 品牌产地 -->
      <el-form-item label="产地" prop="brandClassId">
        <el-select v-model="form.brandClassId" placeholder="请选择产地" clearable :disabled="form.brandClassId != null && form.brandClassId !='' && !isEdit ">
          <el-option v-for="option in brandClassifyOptions" :key="option.id" :label="option.className" :value="String(option.id)"></el-option>
        </el-select>
      </el-form-item>

      <!-- 文件上传（文案随类型变化） -->
      <el-form-item label="品牌LOGO" prop="brandImg">
        <!-- 上传区域 -->
        <div class="avatar-uploader"
             :class="isEdit ? '' : {'disabled' : form.brandImg != '' && form.imgStatus != 1}"
             @click="isEdit ? openFile() : form.brandImg == '' || form.imgStatus == 1 ? openFile() : null">
          <img v-if="form.brandImg" :src="form.brandImg" class="avatar" />
          <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>

          <!-- 隐藏的上传组件 -->
          <el-upload ref="uploadRef" style="display: none" :show-file-list="false" :http-request="(param) => customUpload(param).then(onBrandImgUploadSuccess)" :before-upload="beforeUpload" />
        </div>
        <div class="upload-tip">图片尺寸为800*800px，支持PNG、JPG和JPEG格式，大小不超过5MB</div>
      </el-form-item>

      <!-- 文件上传（文案随类型变化） -->
      <el-form-item v-if="form.brandType === '2'" label="品牌授权书" prop="brandAuthorization">
        <!-- 上传区域 -->
        <div class="avatar-uploader" @click="openFiles">
          <img v-if="form.brandAuthorization" :src="form.brandAuthorization" class="avatar" />
          <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>

          <!-- 隐藏的上传组件 -->
          <el-upload ref="uploadAuthRef" style="display: none" :show-file-list="false" :http-request="(param) => customUpload(param).then(onBrandAuthorizationUploadSuccess)" :before-upload="beforeUpload" />
        </div>
        <div class="upload-tip">支持PNG、JPG和JPEG格式，大小不超过5MB</div>
      </el-form-item>

      <!-- 区域 -->
      <el-form-item :label="form.brandType === '1' ? '可售区域' : '代理区域'" prop="saleRegion">
        <el-cascader
          v-model="form.saleRegion"
          :options="regionTree"
          :props="cascaderProps"
          collapse-tags
          clearable
          style="width: 100%"
        />
      </el-form-item>
    </el-form>

    <template #footer>
      <el-button @click="close">取消</el-button>
      <el-button type="primary" :loading="loading" @click="submit">确定</el-button>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, reactive, nextTick, computed,watch } from "vue";
import { ElMessage, FormInstance, FormRules } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import baseService from "@/service/baseService";
import regionData from "@/assets/data/address.json";
import type { UploadRequestOptions } from "element-plus";
import { debounce } from "lodash";

const emit = defineEmits(["success"]);

/* 弹窗控制 */
const visible = ref(false);
const isEdit = ref(false);
const loading = ref(false);
const formRef = ref<FormInstance>();
const brandLoading = ref(false);
const brandOptions = ref([]);
const brandName = computed(() => form.brand?.brandName || "");
const brandId = computed(() => form.brand?.id || null);

/* 表单字段 */
const form = reactive({
  id: undefined as number | undefined,
  brandType: "1",
  brandName: "",
  userId: "",
  brandImg: "",
  status: "0",
  brandAuthorization: "",
  brandClassId: "",
  brand: null,
  saleRegion: [] as string[],
  imgStatus: 1
});

// 处理键盘事件，禁止输入空格
const handleKeydown = (event: KeyboardEvent) => {
  if (event.key === ' ') {
    event.preventDefault();
    ElMessage.warning('品牌名称不能包含空格');
  }
};

const handleNoSpaceInput = (field: string, value: string) => {
  // 移除所有空格
  const noSpaceValue = value.replace(/\s/g, "");

  // 根据字段名更新对应的表单字段
  switch (field) {
    case "brandName":
      form.brandName = noSpaceValue;
      break;
    case "brandNames":
      form.brandName = noSpaceValue;
      break;
  }
};

// 产地选项
const brandClassifyOptions = ref<any[]>([]);

/* 区域数据 */
const regionTree = regionData;
/* 把整棵树 value 全部转字符串 */
(function toStr(nodes: any[]) {
  nodes.forEach((n) => {
    n.value = String(n.value);
    if (n.children) toStr(n.children);
  });
})(regionTree);

/* 再生成 Set */
const regionFlatSet = new Set<string>();
(function collect(nodes: any[]) {
  nodes.forEach((node) => {
    regionFlatSet.add(node.value);
    if (node.children) collect(node.children);
  });
})(regionTree);

/* 校验规则 */
const rules: FormRules = {
  brandType: [{ required: true, message: "请选择品牌类型", trigger: "change" }],
  brandName: [
    {
      required: true,
      validator: (_, __, cb) => {
        if (!form.brand) cb(new Error("请选择或输入品牌名称"));
        else cb();
      },
      trigger: "change"
    }
  ],
  brandImg: [{ required: true, message: "请上传文件", trigger: "change" }],
  brandClassId: [{ required: true, message: "请选择品牌产地", trigger: "change" }],
  saleRegion: [{ required: true, message: "请选择区域", trigger: "change" }]
};

const uploadRef = ref<any>();
const uploadAuthRef = ref<any>();

function openFile() {
  uploadRef.value?.$el.querySelector("input[type=file]").click();
}

function openFiles() {
  uploadAuthRef.value?.$el.querySelector("input[type=file]").click();
}

// 获取分类列表
const getBrandClassifyList = () => {
  baseService
    .get("/base/basebrandclassify/queryList2")
    .then((res) => {
      brandClassifyOptions.value = res.data;
    })
    .catch((error) => {
      console.error("获取分类数据出错:", error);
      ElMessage.error("获取分类数据出错");
    });
};

// // 在组件初始化时执行品牌列表查询
// const getBrandList = async () => {
//   try {
//     const res = await baseService.get("/base/basebrand/list/");
//     brandOptions.value = res.data.list || [];
//   } catch (error) {
//     ElMessage.error("获取品牌列表失败");
//     brandOptions.value = [];
//   }
// };

// 远程搜索
const queryBrand = debounce(async (keyword: string) => {
  // 移除搜索关键词中的空格
  const cleanKeyword = keyword?.replace(/\s/g, '');
  /* 空字符不查询 */
  if (!cleanKeyword) {
    brandOptions.value = [];
    return;
  }
  brandLoading.value = true;
  try {
    const res = await baseService.get("/base/basebrand/list/", {
      page: 1,
      limit: 50,
      brandName: cleanKeyword
    });
    let list = res.data.list;

    // 根据清理后的关键字过滤品牌列表
    if (cleanKeyword) {
      const filteredList = list.filter((b: any) =>
        b.brandName && b.brandName.replace(/\s/g, '').includes(cleanKeyword)
      );

      if (filteredList.length === 0) {
        filteredList.unshift({ id: null, brandName: cleanKeyword });
      }

      list = filteredList;
    }

    brandOptions.value = list;
  } catch (error) {
    ElMessage.error("获取品牌列表失败");
    brandOptions.value = [];
  } finally {
    brandLoading.value = false;
  }
},200);

// 选中回调
function handleBrandChange(val: any) {
  if (typeof val === "string") {
    // 用户手动输入品牌名称，移除空格
    const cleanBrandName = val.replace(/\s/g, '');
    form.brand = {
      id: null,
      brandName: cleanBrandName
    };
  } else if (val && typeof val === "object") {
    // 用户从下拉列表中选择品牌，确保品牌名称没有空格
    const cleanBrandName = val.brandName ? val.brandName.replace(/\s/g, '') : '';
    form.brand = {
      id: val.id,
      brandName: cleanBrandName
    };

    if (val.id != null){
      form.brandClassId = String(val.brandClassId);
      form.brandImg = val.imgUrl || "";
      form.imgStatus = 0;
    } else {
      form.brandClassId = "";
      form.brandImg = "";
      form.imgStatus = 1;
    }
  } else {
    form.brand = null;
  }

  // 同步更新form.brandName（确保没有空格）
  form.brandName = form.brand ? form.brand.brandName : "";
}

/* 新增：正在上传中的文件计数 */
const uploadingCount = ref(0)

/* 自定义上传函数 */
const customUpload = async ({ file }: UploadRequestOptions) => {
  uploadingCount.value++
  const fd = new FormData()
  fd.append('file', file)

  try {
    const { url } = await baseService.post('/sys/oss/upload', fd, {
      headers: { 'Content-Type': 'multipart/form-data' }
    })
    return url
  } catch (e: any) {
    ElMessage.error(e?.message || '上传失败')
    throw e
  } finally {
    uploadingCount.value--
  }
}

// 品牌LOGO上传成功处理
const onBrandImgUploadSuccess = (url: string) => {
  form.brandImg = url;
  nextTick(() => formRef.value?.validateField("brandImg"));
};

// 品牌授权书上传成功处理
const onBrandAuthorizationUploadSuccess = (url: string) => {
  form.brandAuthorization = url;
  nextTick(() => formRef.value?.validateField("brandAuthorization"));
};

/* 上传前校验 */
const beforeUpload = (file: File) => {
  const allow = ["image/png", "image/jpg", "image/jpeg"].includes(file.type);
  const limit = file.size / 1024 / 1024 < 5;
  if (!allow) ElMessage.error("仅支持 PNG、JPG、JPEG 格式");
  if (!limit) ElMessage.error("文件大小不能超过 5MB");
  return allow && limit;
};

/* 打开弹窗 */
const open = (row?: any) => {
  formRef.value?.resetFields();
  resetForm();
  isEdit.value = !!row;

  if (row) {
    form.id = row.id;
    form.brandType = String(row.brandType);
    form.brandName = row.brandName;
    form.userId = row.userId;
    form.brandClassId = row.brandClassId;
    form.brandImg = row.brandImg || "";
    form.brandAuthorization = row.brandAuthorization || "";

    baseService
      .get("/noc/authbrandaudit/info/" + row.id)
      .then((res) => {
        form.brand = {
          id: res.authBrandAudit.brand.id,
          brandName: res.authBrandAudit.brand.brandName
        };

        const names = res.authBrandAudit?.saleRegion || '';
        form.saleRegion = String(names)
          .split(',')
          .map(n => getCodeByRegionName(n.trim()))
          .filter(Boolean) as string[];
      })
      .catch((error) => {
        ElMessage.error("获取可售地区失败");
      });
  }

  visible.value = true;
};

/* 关闭弹窗 */
const close = () => {
  visible.value = false;
};

/* 重置表单 */
const resetForm = () => {
  form.id = undefined;
  form.brandType = "1";
  form.brandName = "";
  form.userId = "";
  form.brandImg = "";
  form.brandAuthorization = "";
  form.brandClassId = "";
  form.saleRegion = [];
  form.brand = null;
};

function getRegionNameByCode(code: string): string {
  const find = (nodes: any[]): string | undefined => {
    for (const node of nodes) {
      if (node.value === code) return node.label;
      if (node.children) {
        const name = find(node.children);
        if (name) return name;
      }
    }
  };
  return find(regionTree) || code;
}

function getCodeByRegionName(name: string): string | undefined {
  const find = (nodes: any[]): string | undefined => {
    for (const node of nodes) {
      if (node.label === name) return node.value;
      if (node.children) {
        const code = find(node.children);
        if (code) return code;
      }
    }
  };
  return find(regionTree);
}

const submit = () => {
  if (uploadingCount.value > 0) {
    ElMessage.warning('文件上传中，请稍等')
    return
  }

  formRef.value?.validate(async (valid) => {
    if (!valid) return
    loading.value = true
    try {
      const params = {
        ...form,
        brandType: String(form.brandType),
        saleRegion: form.saleRegion
          .map((code) => getRegionNameByCode(code))
          .join(','),
        brandName: form.brand?.brandName || '',
        brand: form.brand
      }
      if (isEdit.value) params.brandName = form.brandName

      if (isEdit.value) {
        await baseService.put('/noc/authbrandaudit/update', params)
        ElMessage.success('修改成功')
      } else {
        await baseService.post('/noc/authbrandaudit/save', params)
        ElMessage.success('新增成功')
      }
      emit('success')
      close()
    } finally {
      loading.value = false
    }
  })
}

/**
 * 配置级联选择器的属性
 */
const cascaderProps = computed(() => ({
  multiple: true,
  checkStrictly: true,
  emitPath: false,
  value: 'value',
  label: 'label',
  disabled: (nodeData: any) => isNodeOrDescendantSelected(nodeData)
}));

/**
 * 检查节点或后代节点是否被选中
 */
const isNodeOrDescendantSelected = (nodeData: any) => {
  return checkAncestorSelected(nodeData.value);
}

/**
 * 检查父节点是否被选中
 */
const checkAncestorSelected = (nodeValue: any) => {
  return form.saleRegion.some(selectedValue => {
    const selectedPath = getFullPath(selectedValue);
    const currentNodePath = getFullPath(nodeValue);

    if (selectedPath.length >= currentNodePath.length) return false;

    for (let i = 0; i < selectedPath.length; i++) {
      if (selectedPath[i] !== currentNodePath[i]) return false;
    }
    return true;
  });
}

/**
 * 获取节点的路径
 */
const getFullPath = (targetValue: any) => {
  const path: any[] = [];

  function findPath(nodes: any[], currentPath: any[] = []) {
    for (const node of nodes) {
      const newPath = [...currentPath, node.value];

      if (node.value === targetValue) {
        path.push(...newPath);
        return true;
      }

      if (node.children && findPath(node.children, newPath)) {
        return true;
      }
    }
    return false;
  }

  if (Array.isArray(regionTree)) {
    findPath(regionTree);
  }

  return path;
}

/**
 * 获取节点的所有子节点值
 */
const getAllChildrenValues = (node: any): string[] => {
  let values: string[] = [];

  if (node.children && node.children.length > 0) {
    node.children.forEach((child: any) => {
      values.push(child.value);
      values = values.concat(getAllChildrenValues(child));
    });
  }

  return values;
}

// 监听选中区域变化
watch(
  () => form.saleRegion,
  (newVal, oldVal) => {
    const added = newVal.filter(item => !oldVal.includes(item));

    let needUpdate = false;
    const updatedSaleRegion = [...newVal];

    added.forEach(selectedValue => {
      const nodePath = getFullPath(selectedValue);
      if (nodePath.length > 0) {
        const selectedNodeValue = nodePath[nodePath.length - 1];

        let targetNode = null;
        const findNode = (nodes: any[]) => {
          for (const node of nodes) {
            if (node.value === selectedNodeValue) {
              targetNode = node;
              return true;
            }
            if (node.children && findNode(node.children)) {
              return true;
            }
          }
          return false;
        };

        findNode(regionTree);

        if (targetNode && targetNode.children) {
          const childrenValues = getAllChildrenValues(targetNode);
          childrenValues.forEach(childValue => {
            const index = updatedSaleRegion.indexOf(childValue);
            if (index > -1) {
              updatedSaleRegion.splice(index, 1);
              needUpdate = true;
            }
          });
        }
      }
    });

    if (needUpdate) {
      form.saleRegion = updatedSaleRegion;
    }
  },
  { deep: true }
);

getBrandClassifyList();

/* 暴露方法 */
defineExpose({ open });
</script>

<style lang="scss" scoped>
.form-tip {
  color: #999;
}
.upload-tip {
  color: #999;
}
.avatar-uploader {
  margin-right: 300px;
  width: 148px;
  height: 148px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  &:hover {
    border-color: var(--el-color-primary);
  }
}
.avatar {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.tip {
  font-size: 12px;
  color: #999;
  line-height: 18px;
  margin-top: 6px;
}
.avatar-uploader {
  position: relative;
  width: 148px;
  height: 148px;
}
.avatar-mask {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.avatar-uploader.disabled {
  cursor: not-allowed;
  border-color: #dcdfe6;
  background-color: #f5f7fa;
  .avatar-uploader-icon {
    color: #c0c4cc;
  }
}
</style>
